package es.usj.redes.dao;

import java.util.Map;
import java.util.HashMap;
/**
 * Clase para la generacion de DAO de acceso a la base de datos
 * 
 * Mediante esta clase se implementa el patron abstract factory 
 * para el patron DAO de acceso a la base de datos.
 * En esta clase crea un patron Singleton y poder acceder de una 
 * manera sencilla, unido al factory, para acceder a los metodos
 * DAO de cada clase. 
 * En esta clase se genera un hashMap para almacenar las instancias 
 * de las clases creadas.
 * @version 1.0
 * @since 1.0
 */
public class DAOFactory {
	
	/**
	 * Map donde se guardan las clases generadas.
	 */
    private Map map;
    /**
     * variable para instanciar la clase
     */
    private static DAOFactory instance;
    /**
     * Constructor que genera una nueva instancia de un hashmap
     */
    private DAOFactory() {
        map = new HashMap();
    }
    /**
     * metodo de acceso al constructor.
     * Empleado por el patron Singleto.
     * @return
     */
    public static DAOFactory getInstance() {
        if(instance == null)
            instance = new DAOFactory();
        return instance;
    }

    public MailJdbcDAO getMailDAO() throws DAOException {
        return (MailJdbcDAO) createDAO(MailJdbcDAO.class);
    }

    public EnviadoJdbcDAO getEnviadoDAO() throws DAOException {
        return (EnviadoJdbcDAO) createDAO(EnviadoJdbcDAO.class);
    }

    public UsersJdbcDAO getUsersDAO() throws DAOException {
        return (UsersJdbcDAO) createDAO(UsersJdbcDAO.class);
    }
    /**
     * Metodo principal de la clase donde se buscara una 
     * clase que se pasa por parametro, en caso que se nula
     * se generara una nueva instancia y se metera en el 
     * hashMap.
     * 
     * @param clazz a buscar.
     * @return instancia de la clase generada.
     * @throws DAOException si hay algun problema al crear el newInstance().
     */
    private Object createDAO(Class clazz) throws DAOException {
        Object obj = map.get(clazz);
        if(obj == null) {
            try {
                    obj = clazz.newInstance();
                    map.put(clazz, obj);
            } catch(Exception e) {
                    throw new DAOException(e);
            }
        }
        return obj;
    }

}
